package ccgrammar;

import java.util.ArrayList;
import java.util.Collections;
import processing.core.PGraphics;
import processing.core.PMatrix3D;
import processing.core.PVector;


public class Face implements Constants{
int id;
int type;
ArrayList<PVector> vertices = new ArrayList<PVector>();

public Face() {
}

public Face(PVector v1, PVector v2, PVector v3) {
	vertices.add(v1);
	vertices.add(v2);
	vertices.add(v3);
}

public Face(PVector v1, PVector v2, PVector v3, PVector v4) {
	vertices.add(v1);
	vertices.add(v2);
	vertices.add(v3);
	vertices.add(v4);
}



public void reverse() {
	Collections.reverse(vertices);
}

public PVector normal() {
	PVector v = PVector.sub(vertices.get(1), vertices.get(0));
	PVector u = PVector.sub(vertices.get(2), vertices.get(0));
	PVector normal = new PVector();
	PVector.cross(v, u, normal);
	normal.normalize();
	return normal;
}

public void addNode(PVector n) {
	vertices.add(n);
	// TODO Auto-generated method stub

}

public PVector getNode(int j) {
	// TODO Auto-generated method stub
	return vertices.get(j);
}


public int getNumVertices() {
	// TODO Auto-generated method stub
	return vertices.size();
}

public float getPerimeter() {
	float sum = 0;
	for (int i = 0; i < getNumVertices(); i++) {
		PVector v1=getNode(i);
		PVector v2=getNode((i + 1) % getNumVertices());
		sum += v1.dist(v2);
	}
	return sum;
}
public PVector getCenter(){
	PVector center=new PVector();
	for (int i = 0; i < getNumVertices(); i++) {
		center.add(getNode(i));
	}
	center.div(getNumVertices());
	return center;
}
public boolean isHorizontal(){
	float z=getNode(0).z;
	for (int i=0;i<getNumVertices();i++){
		if (getNode(i).z!=z)return false;
	}
	return true;
}
public PMatrix3D getMatrixXY() {
	PMatrix3D rot = new PMatrix3D();
	PVector p0=getNode(0);
	rot.translate(-p0.x, -p0.y, -p0.z);
	if (isHorizontal())return rot;
	PVector s = new PVector(0, 0, 1); // is already normalized (meaning is
										// has length 1)
	PVector normal = normal();
	PVector r = s.cross(normal);
	float a = (float) Math.acos(s.dot(normal));
	rot.rotate(-a, r.x, r.y, r.z);
	return rot;
}
public Face copyDeep() {
	Face face=new Face();
	for (int i=0;i<getNumVertices();i++){
		face.addNode(getNode(i).get());
	}
	return face;
}
public void transform(PMatrix3D matrix) {
	for (int i = 0; i < getNumVertices(); i++) {
		PVector v=getNode(i);
		matrix.mult(v, v);
	}
}
public void display3D(PGraphics g){
	int nNodes = getNumVertices();
	if (nNodes == 4) {
		g.beginShape(PGraphics.QUADS);
		for (int i = 0; i < nNodes; i++) {
			PVector v=getNode(i);
			g.vertex(v.x,v.y,v.z);
		}
		g.endShape();
	} else if (nNodes == 3) {
		g.beginShape(PGraphics.TRIANGLES);
		for (int i = 0; i < nNodes; i++) {
			PVector v=getNode(i);
			g.vertex(v.x,v.y,v.z);
		}
		g.endShape();
	} else {
		g.beginShape();
		for (int i = 0; i < nNodes; i++) {
			PVector v=getNode(i);
			g.vertex(v.x,v.y,v.z);
		}
		g.endShape(PGraphics.CLOSE);
	}
}

}
